#include "ScratchActiveX.h"

#ifdef _WIN32
#ifdef _DEBUG
   #include <crtdbg.h>
   #undef THIS_FILE
   static char THIS_FILE[] = __FILE__;
   #define new       new( _NORMAL_BLOCK, __FILE__, __LINE__)
   #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif

// {BD3F23C0-D43E-11CF-893B-00AA00BDCE1A}
EXTERN_C const IID IID_Secret1 = { 0xBD3F23C0, 0xD43E, 0x11CF, 0x89, 0x3B, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x1A };
// {B6EA2050-048A-11D1-82B9-00C04FB9942E}
EXTERN_C const IID IID_Secret4 = { 0xB6EA2050, 0x048A, 0x11D1, 0x82, 0xB9, 0x00, 0xC0, 0x4F, 0xB9, 0x94, 0x2E };

using namespace acme::scratch;

void StandardDispatch::init(INTERFACEDATA* pidata,IUnknown* punkOuter,void* pClass)
{
  LCID lcid=LOCALE_SYSTEM_DEFAULT;
  CreateDispTypeInfo(pidata,lcid,&_iTypeInfo);

  HRESULT hr = CreateStdDispatch(punkOuter,pClass,_iTypeInfo,(IUnknown**)&_iDispatch);
}

GenericDispatch::GenericDispatch()
{
  Trace::Write(TEXT("GenericDispatch Created"));
}

GenericDispatch::~GenericDispatch()
{
  Trace::Write(TEXT("GenericDispatch Destroyed"));
}

void GenericDispatch::init(INTERFACEDATA* pidata,void* pClass)
{
  _pClass=pClass;
  LCID lcid=LOCALE_SYSTEM_DEFAULT;
  HRESULT he = CreateDispTypeInfo(pidata,lcid,&_iTypeInfo);
}

HRESULT GenericDispatch::QueryInterface(REFIID riid,void **ppvObject)
{
  if(riid == IID_IUnknown || riid == IID_IDispatch)
    *ppvObject = (IDispatch*)this;
  else
  {
    Trace::Write(TEXT("GenericDispatch::QueryInterface(*unknown*)"));
    *ppvObject = 0;
    return E_NOINTERFACE;
  }
  AddRef();
  return S_OK;
}

HRESULT GenericDispatch::GetTypeInfoCount(UINT *pctinfo)
{
  *pctinfo = 1;
  return S_OK;
}

HRESULT GenericDispatch::GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)
{
  *ppTInfo = _iTypeInfo;
  return (*ppTInfo)?S_OK:S_FALSE;
}

HRESULT GenericDispatch::GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)
{
  return DispGetIDsOfNames(_iTypeInfo,rgszNames,cNames,rgDispId);
}

HRESULT GenericDispatch::Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
{
  HRESULT hr = DispInvoke(_pClass,_iTypeInfo,dispIdMember,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
  if(!SUCCEEDED(hr)){
    Trace::WriteFormat(TEXT("GenericDispatch::Invoke - UnknownDispid: %d"),dispIdMember);
  }
  return hr;
}



ActiveXFrame::ActiveXFrame()
{
  Trace::Write(TEXT("ActiveXFrame Created"));

}

ActiveXFrame::~ActiveXFrame()
{
  Trace::Write(TEXT("ActiveXFrame Destroyed"));
}

HRESULT ActiveXFrame::QueryInterface(REFIID riid,void **ppvObject)
{
  if(riid == IID_IUnknown || riid == IID_IOleWindow || riid == IID_IOleInPlaceUIWindow || riid == IID_IOleInPlaceFrame)
    *ppvObject = (IOleInPlaceFrame*)this;
  // Interfaces The WebBrowser asks for during SetClientSite (or later)
  //else if(riid == IID_IServiceProvider || riid == IID_IDispatch ||
    // Interfaces the WebBrowser asks for during DoVerb(ACTIVATEINPLACE)
    //riid == IID_IOleCommandTarget)
//  {
//    *ppvObject = 0;
//    return E_NOINTERFACE;
//  }
  else
  {
    Trace::Write(TEXT("ActiveXFrame::QueryInterface(*unknown*)"));
    *ppvObject = 0;
    return E_NOINTERFACE;
  }
  AddRef();
  return S_OK;
}

//ULONG ActiveXFrame::AddRef( void) 
//{
//  return InterlockedIncrement(&_cRef);
//}
//
//ULONG ActiveXFrame::Release( void) 
//{
//  ULONG ret = InterlockedDecrement(&_cRef);
//  if(!ret)
//    delete this;
//  return ret;
//}

HRESULT ActiveXFrame::GetWindow(HWND *phwnd)
{
  Trace::Warn(TEXT("ActiveXFrame::GetWindow"));
  return E_NOTIMPL;
}

HRESULT ActiveXFrame::ContextSensitiveHelp(BOOL fEnterMode)
{
  Trace::Warn(TEXT("ActiveXFrame::ContextSensitiveHelp"));
  return E_NOTIMPL;
}

HRESULT ActiveXFrame::GetBorder(LPRECT lprectBorder)
{
  Trace::Warn(TEXT("ActiveXFrame::GetBorder"));
  return E_NOTIMPL;
}

HRESULT ActiveXFrame::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
{
  Trace::Warn(TEXT("ActiveXFrame::RequestBorderSpace"));
  return E_NOTIMPL;
}

HRESULT ActiveXFrame::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
{
  Trace::Warn(TEXT("ActiveXFrame::SetBorderSpace"));
  return E_NOTIMPL;
}

HRESULT ActiveXFrame::SetActiveObject(IOleInPlaceActiveObject *pActiveObject,LPCOLESTR pszObjName)
{
  Trace::WriteFormat(TEXT("ActiveXFrame::SetActiveObject(%s)"),pszObjName);
  _active = pActiveObject;
  return S_OK;
}

HRESULT ActiveXFrame::InsertMenus(HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
  Trace::Warn(TEXT("ActiveXFrame::InsertMenus"));
  return E_NOTIMPL;
}

HRESULT ActiveXFrame::SetMenu(HMENU hmenuShared,HOLEMENU holemenu,HWND hwndActiveObject)
{
  TCHAR title[64];
  TCHAR wndclass[64];
  GetWindowText(hwndActiveObject,title,sizeof title);
  GetClassName(hwndActiveObject,wndclass,sizeof wndclass);
  Trace::WriteFormat(TEXT("ActiveXFrame::SetMenu( wnd:[%s,%s])"),title,wndclass);
  return S_OK;
}

HRESULT ActiveXFrame::RemoveMenus(HMENU hmenuShared)
{
  Trace::Warn(TEXT("ActiveXFrame::RemoveMenus"));
  return E_NOTIMPL;
}

HRESULT ActiveXFrame::SetStatusText(LPCOLESTR pszStatusText)
{
  Trace::WriteFormat(TEXT("ActiveXFrame::SetStatusText: %s"),pszStatusText);
  return S_OK;
}

HRESULT ActiveXFrame::EnableModeless(BOOL fEnable)
{
  Trace::WriteFormat(TEXT("ActiveXFrame::EnableModeless(%s)"),fEnable?TEXT("true"):TEXT("false"));
  return S_OK;
}

HRESULT ActiveXFrame::TranslateAccelerator(LPMSG lpmsg,WORD wID)
{
  Trace::Warn(TEXT("ActiveXFrame::TranslateAccelerator"));
  return E_NOTIMPL;
}


ActiveXSite::ActiveXSite()//:_cRef(1)
{
  Trace::Write(TEXT("ActiveXSite Created"));
}

ActiveXSite::~ActiveXSite()
{
  Trace::Write(TEXT("ActiveXSite Destroyed"));

  close();
}

void ActiveXSite::init(REFCLSID clsid, IOleInPlaceFrame* frame, REFIID riid, void** ppvObject)
{
  _iOleFrame = frame;
  HRESULT hr = CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,riid,ppvObject);
  ((IUnknown*)*ppvObject)->QueryInterface(IID_IOleObject,(void**)&_iOleObject);
  _iOleObject->SetHostNames(TEXT("Container"),TEXT(""));
  _iOleObject->SetClientSite(this);
}

void ActiveXSite::close()
{
  if(_iOleObject)
    _iOleObject->Close(OLECLOSE_NOSAVE);
  _iOleObject=0;
}

void ActiveXSite::resizeTo(int x, int y, int w, int h)
{
  Rect frame(x,y,w,h);
  if(_iOleInPlaceObject)
    _iOleInPlaceObject->SetObjectRects(&frame,&frame);
}

HRESULT ActiveXSite::QueryInterface( 
  REFIID riid,
  void **ppvObject)
{
  if(riid == IID_IUnknown || riid == IID_IOleClientSite)
    *ppvObject = (IOleClientSite*)this;
  else if(riid == IID_IOleWindow || riid == IID_IOleInPlaceSite)
    *ppvObject = (IOleInPlaceSite*)this;
  // Interfaces The WebBrowser asks for during SetClientSite (or later)
  else if(riid == IID_IServiceProvider || riid == IID_IDispatch ||
    // Interfaces the WebBrowser asks for during DoVerb(ACTIVATEINPLACE)
    riid == IID_IOleCommandTarget || riid == IID_IOleControlSite ||
    // After navigate
    riid == IID_Secret1 || riid == IID_IOleInPlaceSiteEx ||
    // while loading
    riid == IID_Secret4 )

  {
    *ppvObject = 0;
    return E_NOINTERFACE;
  }
  else
  {
    Trace::Warn(TEXT("ActiveXSite::QueryInterface(*unknown*)"));
    *ppvObject = 0;
    return E_NOINTERFACE;
  }
  AddRef();
  return S_OK;
}

HRESULT ActiveXSite::SaveObject( void)
{
  Trace::Warn(TEXT("ActiveXSite::SaveObject"));
  return E_NOTIMPL;
}

HRESULT ActiveXSite::GetMoniker( 
    DWORD dwAssign,
    DWORD dwWhichMoniker,
    IMoniker **ppmk) 
{
  Trace::Warn(TEXT("ActiveXSite::GetMoniker"));
  return E_NOTIMPL;
}
        
HRESULT ActiveXSite::GetContainer( 
    IOleContainer **ppContainer)
{
  Trace::Write(TEXT("ActiveXSite::GetContainer"));
  *ppContainer=NULL;
  return E_NOTIMPL;
}

HRESULT ActiveXSite::ShowObject( void)
{
  Trace::Write(TEXT("ActiveXSite::ShowObject"));
  // We could defer making the control visible until here?
  return S_OK;
}

HRESULT ActiveXSite::OnShowWindow( 
    BOOL fShow)
{
  Trace::Warn(TEXT("ActiveXSite::OnShowWindow"));
  return E_NOTIMPL;
}

HRESULT ActiveXSite::RequestNewObjectLayout( void)
{
  Trace::Warn(TEXT("ActiveXSite::RequestNewObjectLayout"));
  return E_NOTIMPL;
}

HRESULT ActiveXSite::GetWindow(HWND *phwnd)
{
  Trace::Warn(TEXT("ActiveXSite::GetWindow"));
  return E_NOTIMPL;
}
HRESULT ActiveXSite::ContextSensitiveHelp(BOOL fEnterMode)
{
  Trace::Warn(TEXT("ActiveXSite::ContextSensitiveHelp"));
  return E_NOTIMPL;
}
HRESULT ActiveXSite::CanInPlaceActivate( void)
{
  Trace::Write(TEXT("ActiveXSite::CanInPlaceActivate"));
  return S_OK;
}
HRESULT ActiveXSite::OnInPlaceActivate( void)
{
  Trace::Write(TEXT("ActiveXSite::OnInPlaceActivate"));
  return _iOleObject->QueryInterface(IID_IOleInPlaceObject,(void**)&_iOleInPlaceObject);
}
HRESULT ActiveXSite::OnUIActivate( void)
{
  Trace::Write(TEXT("ActiveXSite::OnUIActivate"));
  return S_OK;
}

HRESULT ActiveXSite::GetWindowContext( 
  IOleInPlaceFrame **ppFrame,
  IOleInPlaceUIWindow **ppDoc,
  LPRECT lprcPosRect,
  LPRECT lprcClipRect,
  LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
  Trace::Write(TEXT("ActiveXSite::GetWindowContext"));
  if(*ppFrame = _iOleFrame)
    (*ppFrame)->AddRef();
  *ppDoc = NULL;
  HWND hwnd;
  GetWindow(&hwnd);
  GetClientRect(hwnd,lprcPosRect);
  GetClientRect(hwnd,lprcClipRect);
  lpFrameInfo->cAccelEntries=0;
  lpFrameInfo->fMDIApp=FALSE;
  lpFrameInfo->haccel=0;
  _iOleFrame->GetWindow(&lpFrameInfo->hwndFrame);
  return S_OK;
}

HRESULT ActiveXSite::Scroll(SIZE scrollExtant)
{
  Trace::Warn(TEXT("ActiveXSite::Scroll"));
  return E_NOTIMPL;
}
HRESULT ActiveXSite::OnUIDeactivate(BOOL fUndoable)
{
  Trace::Write(TEXT("ActiveXSite::OnUIDeactivate"));
  return S_OK;
}
HRESULT ActiveXSite::OnInPlaceDeactivate( void)
{
  Trace::Write(TEXT("ActiveXSite::OnInPlaceDeactivate"));
  _iOleInPlaceObject=0;
  return S_OK;
}
HRESULT ActiveXSite::DiscardUndoState( void)
{
  Trace::Warn(TEXT("ActiveXSite::DiscardUndoState"));
  return E_NOTIMPL;
}
HRESULT ActiveXSite::DeactivateAndUndo( void)
{
  Trace::Warn(TEXT("ActiveXSite::DeactivateAndUndo"));
  return E_NOTIMPL;
}
HRESULT ActiveXSite::OnPosRectChange(LPCRECT lprcPosRect)
{
  Trace::Warn(TEXT("ActiveXSite::OnPosRectChange"));
  return E_NOTIMPL;
}


#include <ExDispid.h>

static PARAMDATA dWebBrowserEvents2ParamData[]={
  //0 BeforeNavigate2()
  {L"",VT_DISPATCH}, // this
  {L"",VT_VARIANT|VT_BYREF }, // url
  {L"",VT_VARIANT|VT_BYREF }, // flags
  {L"",VT_VARIANT|VT_BYREF }, // targetFrame
  {L"",VT_VARIANT|VT_BYREF }, // postData
  {L"",VT_VARIANT|VT_BYREF }, // headers
  {L"",VT_BOOL|VT_BYREF }, // Cancel
  // 7 Command State Change
  {L"",VT_I4},
  {L"",VT_BOOL},
  // 9 PropertyChange, StatusTextChange
  {L"",VT_BSTR},
  // 10 ProgressChange
  {L"",VT_I4},
  {L"",VT_I4},
  // 12
  {L"",VT_BOOL},
  {L"",VT_BOOL|VT_BYREF},
};

static METHODDATA dWebBrowserEvents2MethodData[] = {
//  Method/Property Name    Parameter List                    Dispatch ID      vtable offset   callconv parameters    wFlags  return type
  { L"BeforeNavigate2",     &dWebBrowserEvents2ParamData[0],  DISPID_BEFORENAVIGATE2,     7,  CC_CDECL,  7,  DISPATCH_METHOD,  VT_EMPTY},
  { L"CommandStateChange",  &dWebBrowserEvents2ParamData[7],  DISPID_COMMANDSTATECHANGE,  2,  CC_CDECL,  2,  DISPATCH_METHOD,  VT_EMPTY},
  { L"DownloadBegin",       NULL ,                            DISPID_DOWNLOADBEGIN,       3,  CC_CDECL,  0,  DISPATCH_METHOD,  VT_EMPTY},
  { L"ProgressChange",      &dWebBrowserEvents2ParamData[10], DISPID_PROGRESSCHANGE,      1,  CC_CDECL,  2,  DISPATCH_METHOD,  VT_EMPTY},
  { L"PropertyChange",      &dWebBrowserEvents2ParamData[9],  DISPID_PROPERTYCHANGE,      6,  CC_CDECL,  1,  DISPATCH_METHOD,  VT_EMPTY},
  { L"StatusTextChange",    &dWebBrowserEvents2ParamData[9],  DISPID_STATUSTEXTCHANGE,    0,  CC_CDECL,  1,  DISPATCH_METHOD,  VT_EMPTY},
  { L"FileDownload",        &dWebBrowserEvents2ParamData[12], DISPID_FILEDOWNLOAD,        26, CC_CDECL,  2,  DISPATCH_METHOD,  VT_EMPTY},
};
static INTERFACEDATA dWebBrowserEvents2InterfaceData =
{
  dWebBrowserEvents2MethodData,_countof(dWebBrowserEvents2MethodData)
};

WebBrowserSite::WebBrowserSite():_cookie(0)
{
}

WebBrowserSite::~WebBrowserSite()
{
  close();
}

void WebBrowserSite::init(IOleInPlaceFrame* frame, WebBrowserEventsDelegate* delegate)
{
  super::init(CLSID_WebBrowser,frame,IID_IWebBrowser2,(void**)&_iWebBrowser2);
  if(delegate)
  {
    //WebBrowserEventsDelegateDispatcher dispatcher;
    DynamicRef<GenericDispatch> dispatcher;
//    DynamicRef<GenericDispatch> dispatcher;
    dispatcher->init(&dWebBrowserEvents2InterfaceData,delegate);
    //dispatcher.init(&dWebBrowserEvents2InterfaceData,(IOleClientSite*)this,delegate);

    ComPtr<IConnectionPointContainer> connectionPointContainer;
    _iWebBrowser2->QueryInterface(IID_IConnectionPointContainer,(void**)&connectionPointContainer);
    ComPtr<IConnectionPoint> iConnectionPoint;
    connectionPointContainer->FindConnectionPoint(DIID_DWebBrowserEvents2,&iConnectionPoint);
    iConnectionPoint->Advise(dispatcher,&_cookie);
  }
}

void WebBrowserSite::close()
{
  if(_cookie)
  {
    ComPtr<IConnectionPointContainer> connectionPointContainer;
    _iWebBrowser2->QueryInterface(IID_IConnectionPointContainer,(void**)&connectionPointContainer);
    ComPtr<IConnectionPoint> iConnectionPoint;
    connectionPointContainer->FindConnectionPoint(DIID_DWebBrowserEvents2,&iConnectionPoint);
    iConnectionPoint->Unadvise(_cookie);
    _cookie=0;
  }
  _iWebBrowser2=0;
  super::close();
}


void WebBrowserSite::loadRequest(string url)
{
  BSTR burl = SysAllocString(url);
  VARIANT var={0};
  var.vt = VT_EMPTY;
  _iWebBrowser2->Navigate(burl,&var,&var,&var,&var);
  SysFreeString(burl);
}


HRESULT STDMETHODCALLTYPE WebBrowserSite::QueryInterface(REFIID riid,void **ppvObject)
{
  if(riid == IID_IDocHostUIHandler )
    *ppvObject = (IDocHostUIHandler2*)this;
  else if(riid == IID_IDocHostShowUI || riid == IID_IDocHostUIHandler2)
  {
    *ppvObject=NULL;
    return E_NOINTERFACE;
  }
  else
    return super::QueryInterface(riid,ppvObject);
  AddRef();
  return S_OK;
}

HRESULT WebBrowserSite::ShowContextMenu(DWORD dwID,POINT *ppt,IUnknown *pcmdtReserved,IDispatch *pdispReserved)
{
  Trace::Write(TEXT("WebBrowserSite::ShowContextMenu"));
  return S_FALSE;
}

HRESULT WebBrowserSite::GetHostInfo(DOCHOSTUIINFO *pInfo)
{
  Trace::Write(TEXT("WebBrowserSite::GetHostInfo"));
  pInfo->dwFlags = 0; //DOCHOSTUIFLAG_DIALOG - disable selection
  return S_OK;
}

HRESULT WebBrowserSite::ShowUI(DWORD dwID,IOleInPlaceActiveObject *pActiveObject,IOleCommandTarget *pCommandTarget,IOleInPlaceFrame *pFrame,IOleInPlaceUIWindow *pDoc)
{
  Trace::Write(TEXT("WebBrowserSite::ShowUI"));
  return S_OK;
}

HRESULT WebBrowserSite::HideUI( void)
{
  Trace::Write(TEXT("WebBrowserSite::HideUI"));
  return S_OK;
}

HRESULT WebBrowserSite::UpdateUI( void)
{
  Trace::Write(TEXT("WebBrowserSite::UpdateUI"));
  return S_OK;
}

HRESULT WebBrowserSite::EnableModeless(BOOL fEnable)
{
  Trace::WriteFormat(TEXT("WebBrowserSite::EnableModeless(%s)"),fEnable?TEXT("true"):TEXT("false"));
  return S_OK;
}

HRESULT WebBrowserSite::OnDocWindowActivate(BOOL fActivate)
{
  Trace::Warn(TEXT("WebBrowserSite::OnDocWindowActivate"));
  return E_NOTIMPL;
}

HRESULT WebBrowserSite::OnFrameWindowActivate(BOOL fActivate)
{
  Trace::Warn(TEXT("WebBrowserSite::OnFrameWindowActivate"));
  return E_NOTIMPL;
}

HRESULT WebBrowserSite::ResizeBorder(LPCRECT prcBorder,IOleInPlaceUIWindow *pUIWindow,BOOL fRameWindow)
{
  Trace::Write(TEXT("WebBrowserSite::ResizeBorder"));
  return S_OK;
}

HRESULT WebBrowserSite::TranslateAccelerator(LPMSG lpMsg,const GUID *pguidCmdGroup,DWORD nCmdID)
{
  Trace::Warn(TEXT("WebBrowserSite::TranslateAccelerator"));
  return E_NOTIMPL;
}

HRESULT WebBrowserSite::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
{
  Trace::Write(TEXT("WebBrowserSite::GetOptionKeyPath"));
  *pchKey=0;
  return S_FALSE;
}

HRESULT WebBrowserSite::GetDropTarget(IDropTarget *pDropTarget,IDropTarget **ppDropTarget)
{
  Trace::Write(TEXT("WebBrowserSite::GetDropTarget"));
  *ppDropTarget=0;
  return E_NOTIMPL;
}

HRESULT WebBrowserSite::GetExternal(IDispatch **ppDispatch)
{
  Trace::Write(TEXT("WebBrowserSite::GetExternal"));
  *ppDispatch=0;
  return S_FALSE;
}

HRESULT WebBrowserSite::TranslateUrl(DWORD dwTranslate,OLECHAR *pchURLIn,OLECHAR **ppchURLOut)
{
  Trace::WriteFormat(TEXT("WebBrowserSite::TranslateUrl(\"%s\")"),pchURLIn);
  *ppchURLOut=NULL;
  return S_FALSE;
}

HRESULT WebBrowserSite::FilterDataObject(IDataObject *pDO,IDataObject **ppDORet)
{
  Trace::Warn(TEXT("WebBrowserSite::Invoke"));
  return E_NOTIMPL;
}

HRESULT WebBrowserSite::GetOverrideKeyPath(LPOLESTR *pchKey,DWORD dw) 
{
  Trace::Write(TEXT("WebBrowserSite::GetOverrideKeyPath"));
  *pchKey=0;
  return S_FALSE;
}



WebView::WebView()
{
}

WebView::~WebView()
{
}


void WebView::initWithFrame(Rect frame,IOleInPlaceFrame* asContentForWindow,WebBrowserEventsDelegate*delegate,void* externalClass,INTERFACEDATA* externalData)
{
//  _frame = asContentForWindow;
  super::init(asContentForWindow,delegate);

  if(externalClass)
  {
    DynamicRef<GenericDispatch> dispatcher;
    //DynamicRef<GenericDispatch> dispatcher;
    dispatcher->init(externalData,externalClass);
    _external = dispatcher;
  }

  HWND hwnd;
  GetWindow(&hwnd);
  HRESULT result = _iOleObject->DoVerb(OLEIVERB_SHOW,NULL,this,0,hwnd,&frame); // OLEIVERB_INPLACEACTIVATE
}

HRESULT WebView::GetExternal(IDispatch **ppDispatch)
{
  if(*ppDispatch = _external)
    (*ppDispatch)->AddRef();
  return (*ppDispatch)?S_OK:S_FALSE;
}

HRESULT WebView::GetWindow(HWND *phwnd)
{
  return _iOleFrame->GetWindow(phwnd);
}

